package com.gxa.luckin.cart.service.impl;

import com.gxa.goods.service.SkuService;
import com.gxa.luckin.cart.service.CartService;
import com.gxa.luckin.core.exception.BusinessException;
import com.gxa.luckin.core.exception.MessageCode;
import com.gxa.luckin.core.pojo.CartItem;
import com.gxa.luckin.core.pojo.Sku;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

/**
 * @author: XHZ
 * @date: 16:47 2021/7/16
 */
@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Resource
    private RedisTemplate redisTemplate;

    /*@Resource
    private SkuService skuService;*/


    public static final String CART = "cart:";

    @Override
    public void addGoodsToCart(Long userId, String skuId, Integer num) throws BusinessException, URISyntaxException {

/*        Object valueId = RpcContext.getContext().getAttachment("userId");
        log.info("dubbo隐式传参获取参数:{}", valueId);*/

//        Sku sku = skuService.findById(skuId);

        RestTemplate restTemplate = new RestTemplate();

        URI uri = new URI("http://localhost:8080/sku/findById");
        // 参数
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
        paramMap.add("id", String.valueOf(skuId));
        Sku sku = restTemplate.postForObject(uri, paramMap, Sku.class);

        CartItem cartItem = (CartItem) redisTemplate.boundHashOps(CART + userId).get(skuId);

        if (!ObjectUtils.isEmpty(cartItem)) {
            //1.先判断该商品是否添加到购物车中，如果已经添加，增加数量
            if (cartItem.getNum() + num > sku.getNum()) {
                //初步库存不足
                throw new BusinessException(MessageCode.ERROR);
            }
            cartItem.setNum(cartItem.getNum() + num);
            cartItem.setTotalPrice(cartItem.getPrice() * cartItem.getNum());
            //2.放入更新的结果到redis中
            redisTemplate.boundHashOps(CART + userId).put(skuId, cartItem);
            return;
        }

        //2.如果没有添加，就创建一个新的购物项
        if (num > sku.getNum()) {
            //初步库存不足
            throw new BusinessException(MessageCode.ERROR);
        }

        cartItem = new CartItem();
        cartItem.setNum(num);
        cartItem.setSkuId(skuId);
        cartItem.setImage(sku.getImage());
        cartItem.setName(sku.getName());
        cartItem.setPrice(sku.getPrice());

        //设置小计  单价*数量
        cartItem.setTotalPrice(sku.getPrice() * num);

        //3.放入redis中
        redisTemplate.boundHashOps(CART + userId).put(skuId, cartItem);

    }

    @Override
    public void updateCartItemNum(Long userId, String skuId, Integer num) {

        CartItem cartItem = (CartItem) redisTemplate.boundHashOps(CART + userId).get(skuId);

        if (!ObjectUtils.isEmpty(cartItem)) {
            //1.先判断该商品是否添加到购物车中，如果已经添加，增加数量
            cartItem.setNum(num);
            cartItem.setTotalPrice(cartItem.getPrice() * cartItem.getNum());
            //2.放入更新的结果到redis中
            redisTemplate.boundHashOps(CART + userId).put(skuId, cartItem);
        }

    }

    @Override
    public void removeCartItem(Long userId, String skuId) {
        redisTemplate.boundHashOps(CART + userId).delete(skuId);
    }

    @Override
    public void clearCart(Long userId) {
        redisTemplate.delete(CART + userId);
    }

    @Override
    public CartItem queryUserCartItem(Long userId, String skuId) throws BusinessException {
        CartItem cartItem = (CartItem) redisTemplate.boundHashOps(CART + userId).get(skuId);
        if (ObjectUtils.isEmpty(cartItem)) {
            throw new BusinessException(MessageCode.ERROR);
        }
        return cartItem;
    }

    @Override
    public Map queryUserCart(Long userId) {
        return redisTemplate.boundHashOps(CART + userId).entries();
    }
}
